package cProto

import (
	"io/ioutil"
	"log"
	"regexp"
	"strings"
)

func Load() {
}

func ParseService(protoFile string) (result []*ProtoService) {
	contentByte, err := ioutil.ReadFile(protoFile)
	if err != nil {
		log.Printf("read file error: %v [%s]", err, protoFile)
		return
	}
	content := string(contentByte)

	serviceReg := regexp.MustCompile(`service +(\w+) *\{([^\}]*)\}`)
	rpcReg := regexp.MustCompile(`rpc +(\w+) *\( *(\w+) *\) *returns *\( *(\w+) *\) *;`)

	serviceMatches := serviceReg.FindAllStringSubmatch(content, -1)
	for _, serviceMatch := range serviceMatches {
		resultItem := &ProtoService{
			ServiceName: serviceMatch[1],
			ServiceRpc:  []*ProtoService_Rpc{},
		}
		rpcMatches := rpcReg.FindAllStringSubmatch(serviceMatch[0], -1)
		for _, rpcMatch := range rpcMatches {
			rpcItem := &ProtoService_Rpc{
				RpcName:     rpcMatch[1],
				RpcRequest:  rpcMatch[2],
				RpcResponse: rpcMatch[3],
			}
			resultItem.ServiceRpc = append(resultItem.ServiceRpc, rpcItem)
		}
		result = append(result, resultItem)
	}

	return
}

func ParseEnum(protoFile string) (result []*ProtoEnum) {
	contentByte, err := ioutil.ReadFile(protoFile)
	if err != nil {
		log.Printf("read file error: %v [%s]", err, protoFile)
		return
	}
	content := string(contentByte)

	enumReg := regexp.MustCompile(`enum +(\w+) *\{([^\}]+)\}`)
	fieldReg := regexp.MustCompile(`(\w+) *= *(\d+) *;`)
	descReg := regexp.MustCompile(`@@desc:(\w+)`)

	enumMatches := enumReg.FindAllStringSubmatch(content, -1)
	for _, enumMatch := range enumMatches {
		resultItem := &ProtoEnum{
			EnumName:   enumMatch[1],
			EnumFields: []*ProtoEnum_Field{},
		}
		fieldMatches := strings.Split(enumMatch[2], "\n")
		for _, fieldMatch := range fieldMatches {
			fieldNameMatches := fieldReg.FindAllStringSubmatch(fieldMatch, -1)
			if len(fieldNameMatches) != 1 {
				continue
			}

			fieldItem := &ProtoEnum_Field{
				EnumFieldName:  fieldNameMatches[0][1],
				EnumFieldValue: fieldNameMatches[0][2],
				EnumFieldDesc:  "",
			}

			descMatches := descReg.FindAllStringSubmatch(fieldMatch, -1)
			if len(descMatches) == 1 {
				fieldItem.EnumFieldDesc = descMatches[0][1]
			}

			resultItem.EnumFields = append(resultItem.EnumFields, fieldItem)
		}

		result = append(result, resultItem)
	}

	return
}

func ParseType(protoFile string) (result []*ProtoType) {
	contentByte, err := ioutil.ReadFile(protoFile)
	if err != nil {
		log.Printf("read file error: %v [%s]", err, protoFile)
		return
	}
	content := string(contentByte)

	typeReg := regexp.MustCompile(`@@type:(\w+)\.(\w+):([\w\[\]\{\}]+)=>([\w\[\]\{\}]+)`)
	typeMatches := typeReg.FindAllStringSubmatch(content, -1)
	for _, typeMatch := range typeMatches {
		resultItem := &ProtoType{
			MessageName: typeMatch[1],
			Field:       typeMatch[2],
			OldType:     typeMatch[3],
			NewType:     typeMatch[4],
		}
		result = append(result, resultItem)
	}

	return
}
